<?php

namespace App\Http\Controllers\Api;

use App\Helper\Http\StatusCode;
use App\Helper\Token\Token;
use App\Http\Controllers\Controller;
use App\Models\Identity;
use App\Models\Server\Decrypt;
use App\Models\Server\WeChatLogin;
use App\Models\User;
use App\Models\UserIdentity;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\JsonResponse;

class UserController extends Controller
{
    private $users;
    private $request;

    public function __construct(Request $request)
    {
        $this->users = new User();
        $this->request = $request;
    }


    public function user():JsonResponse
    {
        $user_id = getUserId();
        $field = ['id', 'nick_name', 'avatar_url', 'sex', 'phone'];
        $userData = $this->users->getOne(['id' => $user_id], $field);
        $userData->identitys = (new UserIdentity())->getAllData(['user_id' => $user_id], ['identity_id']);
        foreach ($userData->identitys as $v) {
            $field = ['id', 'name', 'p_id'];
            $v->identity = (new Identity())
                ->getOne(['id' => $v->identity_id], $field);
            $v->identity->p_identitys = (new Identity())
                ->getOne(['id' => $v->identity->p_id], $field);
        }
        return $this->success($userData);
    }

    public function phone(): JsonResponse
    {
        $input = $this->request->all();
        $validator = Validator::make($input, [
            'encryptedData' => 'required',
            'iv' => 'required',
        ], [
            'encryptedData.required' => 'encryptedData必填',
            'iv.required' => 'iv必填',
        ]);
        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }
        $user_id = getUserId();
        $userObj = $this->users->getOne(['id' => $user_id]);
        $errCode = (new Decrypt($userObj->session_key))
            ->decryptData($input['encryptedData'], $input['iv'], $data);
        if ($errCode == 0) {
            $data = json_decode($data, true);
            # 手机号码必须唯一
            $phoneOnly = $this->users->getOne(['phone' => $data['phoneNumber']]);
            if ($phoneOnly) {
                return $this->error('该手机号码已绑定,请输入新的号码');
            }
            $userObj->update(['phone' => $data['phoneNumber']]);
            return $this->success();
        } else {
            return $this->error($errCode);
        }
    }

    public function logout(): JsonResponse
    {
        $user_id = getUserId();
        $prefix = env('REDIS_HOME_PREFIX');
        (new Token())->del($prefix, $user_id);
        return $this->success();
    }

    public function login(): JsonResponse
    {
        $input = $this->request->all();
        $validator = Validator::make($input, [
            'code' => 'required',
            'nick_name' => 'required',
            'avatar_url' => 'required',
            'sex' => 'required|in:0,1,2' # 性别: 0未知, 1男 ,2女
        ], [
            'code.required' => 'code必填',
            'nick_name.required' => 'nick_name必填',
            'avatar_url.required' => 'avatar_url必填',
            'sex.required' => 'sex必填',
            'sex.in' => 'sex只能为0,1,2',
        ]);
        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }
        # 兼容本地调试
        # 本地直接根据code, 默认code为id, 直接生成对应的token
        $prefix = env('REDIS_HOME_PREFIX');
        if (env('APP_ENV') == 'local') {
            $json['token'] = (new Token())->createToken($prefix, $input['code']);
            return $this->success($json);
        }
        # 获取小程序openid和session_key
        $auth_data = (new WeChatLogin())->login($input['code']);
        if ($auth_data['code'] == StatusCode::SERVICE_NETWORK) {
            return $this->error($auth_data['msg']);
        }
        $body = json_decode($auth_data['data'], true);
        if (!isset($body['openid']) or !isset($body['session_key'])) {
            # code been used, hints: [ req_id: 1Ead263Vf-i3cH ]
            # {"errCode":40029,"errMsg":"invalid code, hints: [ req_id: HFad_2Nre-dE2_ca ]"}
            # 获取不到openid或者session_key, 基本不存在这种情况
            return $this->error('授权登录失败');
        }
        $input['session_key'] = $body['session_key'];
        $input['open_id'] = $body['openid'];
        # 根据openid判断用户是否存在, 不存在则创建
        $user = $this->users->getOne(['open_id' => $body['openid']]);
        if ($user) {
            $user->update(['session_key' => $body['session_key']]);
            $user_id = $user->id;
        } else {
            $userCreate = User::create($input);
            $user_id = $userCreate->id;
        }
        $json['token'] = (new Token())->createToken($prefix, $user_id);
        return $this->success($json);
    }
}
